/**
 * File: sqlite.js.
 * Author: W A P.
 * Email: 610585613@qq.com.
 * Datetime: 2018/07/24.
 */
const { app,ipcMain,BrowserWindow } = require('electron')
let { init, exec, sql, transaction } = require('mysqls')

var fs = require('fs');
var sqlite3 = require('sqlite3').verbose();
const config = require('../../config/index');
 
console.log("load sqllite.............")
var DB = DB || {};


var sqlMgr={
    isCon : false,
    initTable(cb){
        sqliteDB.createTable(`CREATE TABLE if not exists moneyinfo (
            day varchar(20) PRIMARY KEY NOT NULL ,-- '日期'
            zzc float(20,3) DEFAULT '0.000' ,-- '总资产'
            zsz float(25,3) DEFAULT '0.000' ,-- '总市值'
            kyzj float(25,3) DEFAULT '0.000' ,-- '可用资金'
            ccyk float(25,3) DEFAULT '0.000' ,-- '持仓盈亏'
            createtime datetime DEFAULT NULL  -- '插入时间'
          )`);
        
        sqliteDB.createTable(`CREATE TABLE if not exists store (
            id INTEGER PRIMARY KEY   AUTOINCREMENT,
            day varchar(20) NOT NULL ,-- '日期',
            code varchar(10) NOT NULL ,-- '代码',
            name varchar(255) DEFAULT NULL ,-- '名称',
            amount int(10) DEFAULT '0' ,-- '数量',
            cbj float(20,3) DEFAULT '0.000' ,-- '成本价',
            curprice float(10,3) DEFAULT '0.000' ,-- '当前价',
            zxsz float(20,3) DEFAULT '0.000' ,-- '最新市值',
            fdyk float(20,3) DEFAULT '0.000' ,-- '浮动盈亏',
            rate float(20,3) DEFAULT '0.000' ,-- '盈亏比例',
            createtime datetime DEFAULT NULL
            ) `);
        
        sqliteDB.createTable(`CREATE TABLE if not exists todayinfo (
            cjbh varchar(30) PRIMARY KEY  ,-- '成交编号',
            cjsj varchar(20) DEFAULT NULL ,-- '时间',
            code varchar(20) DEFAULT NULL ,-- '代码',
            name varchar(20) DEFAULT NULL ,-- '名称',
            Mmlb varchar(10) DEFAULT NULL,
            mmsm varchar(20) DEFAULT NULL ,-- '方向',
            cjsl varchar(20) DEFAULT NULL ,-- '数量',
            cjjg varchar(20) DEFAULT NULL ,-- '成交价格',
            cjje float(20,3) DEFAULT NULL ,-- '成交金额',
            createtime datetime DEFAULT NULL
          )`);
        
        
        sqliteDB.createTable(`CREATE TABLE if not exists tradehis (
            tradeno varchar(20) NOT NULL PRIMARY KEY ,-- '编号',
            day varchar(20) NOT NULL ,-- '日期',
            time varchar(10) NOT NULL ,-- '时间',
            code varchar(10) NOT NULL ,-- '代码',
            name varchar(10) NOT NULL ,-- '名称',
            isBuy tinyint(1) DEFAULT NULL ,-- '卖买方向 1买入 0卖出',
            type varchar(10) DEFAULT NULL ,-- '交易类别',
            amount int(10) DEFAULT '0' ,-- '数量',
            leftNum int(10) DEFAULT '0' ,-- '股票余额',
            price float(10,3) DEFAULT '0.000' ,-- '均价',
            money float(10,3) DEFAULT '0.000' ,-- '金额',
            fee1 float(10,3) DEFAULT '0.000' ,-- '佣金',
            fee2 float(10,3) DEFAULT '0.000' ,-- '规费',
            fee3 float(10,3) DEFAULT '0.000' ,-- '印花税',
            fee4 float(10,3) DEFAULT '0.000' ,-- '过户费',
            leftmoney float(10,3) DEFAULT '0.000' ,-- '剩余金额',
            account varchar(30) DEFAULT NULL ,-- '股东账号',
            market varchar(20) DEFAULT NULL -- '交易市场',
          ) `);

          
        sqliteDB.createTable(`CREATE TABLE if not exists bank (
          tradeno varchar(20) NOT NULL PRIMARY KEY ,-- '编号 day+time',
          day varchar(20) NOT NULL ,-- '日期',
          time varchar(20) DEFAULT NULL ,-- '时间',
          name varchar(20) DEFAULT NULL ,-- '名称',
          oper varchar(20) DEFAULT NULL ,-- '操作',
          status int(3) DEFAULT NULL ,-- '状态',
          money float(10,3) DEFAULT '0.000' ,-- '发生金额',
          remark varchar(20) DEFAULT NULL ,-- '备注',
          createtime datetime DEFAULT NULL
        )`);

        
        sqliteDB.createTable(`CREATE TABLE if not exists jj (
          tradeno varchar(20) NOT NULL PRIMARY KEY ,-- '编号 day+code',
          day varchar(20) NOT NULL ,-- '日期',
          code varchar(20) NOT NULL ,-- '基金代码',
          name varchar(20) NOT NULL ,-- '基金名称',
          money float(10,3) DEFAULT '0.000' ,-- '发生金额',
          createtime datetime DEFAULT NULL
        )`);

        
        sqliteDB.createTable(`CREATE TABLE if not exists lhdata (
          id varchar(20) NOT NULL PRIMARY KEY ,-- '编号 day+code',
          day varchar(20) NOT NULL ,-- '日期',
          code varchar(20) NOT NULL ,-- '代码',
          name varchar(20) NOT NULL ,-- '名称',
          rise float(15,3) DEFAULT '0.000' ,-- '当日涨幅',
          price float(15,3) DEFAULT '0.000' ,-- '当日价格',
          jmoney float(15,3) DEFAULT '0.000' ,-- '净买入',
          buyrate float(15,3) DEFAULT '0.000' ,-- '买入占比',
          buymoney float(15,3) DEFAULT '0.000' ,-- '总买入',
          salemoney float(15,3) DEFAULT '0.000' ,-- '总卖出',
          reason varchar(100) NOT NULL ,-- '上榜原因',
          createtime datetime DEFAULT NULL
        )`);

        sqliteDB.createTable(`CREATE TABLE if not exists gzdata (
          id varchar(20) NOT NULL PRIMARY KEY ,-- '编号 day+code',
          day varchar(20) NOT NULL ,-- '日期',
          code varchar(20) NOT NULL ,-- '代码',
          name varchar(20) NOT NULL ,-- '名称',
          rise float(15,3) DEFAULT '0.000' ,-- '当日涨幅',
          price float(15,3) DEFAULT '0.000' ,-- '当日价格',
          jmoney float(15,3) DEFAULT '0.000' ,-- '净买入',
          buyrate float(15,3) DEFAULT '0.000' ,-- '买入占比',
          buymoney float(15,3) DEFAULT '0.000' ,-- '总买入',
          salemoney float(15,3) DEFAULT '0.000' ,-- '总卖出',
          createtime datetime DEFAULT NULL
        )`);

        if(cb){
            cb();
        }
    },
    getSucc(data,param){
      var res = { succ: true, err:"", data:data }
      if(param && param.cb){
        param.cb(res);
      }
      return res;
    },
    getFail(err,param){
      console.error("db exec error",err)
      var res = { succ: false, err:err.message || err, data:null }
      if(param && param.cb){
        param.cb(res);
      }
      return res;
    },
    insertLHData(param){
        sqliteDB.executeSql("delete from lhdata where id="+param.objInfo.id,()=>{
            sql.sqlObj = {};
            var sqlobj = sql.table('lhdata').data(param.objInfo).insert();
            sqliteDB.executeSql(sqlobj,(err)=>{
                if(err){ this.getFail(err,param) }
                else{ this.getSucc("",param) }
            });
        });
      
    },
    insertGZData(param){
        sqliteDB.executeSql("delete from gzdata where id="+param.objInfo.id,()=>{
            sql.sqlObj = {};
            var sqlobj = sql.table('gzdata').data(param.objInfo).insert();
            sqliteDB.executeSql(sqlobj,(err)=>{
                if(err){ this.getFail(err,param) }
                else{ this.getSucc("",param) }
            });
        });
      
    },
    insertJJ(param){
      sql.sqlObj = {};
      var sqlobj = sql.table('jj').data(param.objInfo).insert();
      sqliteDB.executeSql(sqlobj,(err)=>{
          if(err){ this.getFail(err,param) }
          else{ this.getSucc("",param) }
      });
    },
    insertBank(param){
      sql.sqlObj = {};
      var sqlobj = sql.table('bank').data(param.objInfo).insert();
      sqliteDB.executeSql(sqlobj,(err)=>{
          if(err){ this.getFail(err,param) }
          else{ this.getSucc("",param) }
      });
    },
    insertHis(param){
        sql.sqlObj = {};
        var sqlobj = sql.table('tradehis').data(param.objInfo).insert();
        sqliteDB.executeSql(sqlobj,(err)=>{
            if(err){ this.getFail(err,param) }
            else{ this.getSucc("",param) }
        });
    },
    queryHis(param){
        sql.sqlObj = {};
        var sqlobj = sql.table('tradehis').where(param.objInfo).select();
        sqliteDB.queryData(sqlobj,(datas,err)=>{
          if(err){ this.getFail(err,param) }
          else{ this.getSucc(datas,param) }
        })
    },
    getCodeList(param){
        sqliteDB.queryData("select code,name,max(day) day FROM tradehis group by code order by day desc,time desc",(datas,err)=>{
          if(err){ this.getFail(err,param) }
          else{ this.getSucc(datas,param) }
        })
    },
    insertMoneyInfo(param){
        
        sqliteDB.executeSql("delete from moneyinfo where day="+param.objInfo.day,()=>{
            sql.sqlObj = {};
            var sqlobj = sql.table('moneyinfo').data(param.objInfo).insert();
            sqliteDB.executeSql(sqlobj,(err)=>{
                if(err){ this.getFail(err,param) }
                else{ this.getSucc("",param) }
            });
        });
      
    },
    insertStore(param){
        var list = param.objInfo;
        if(list.length<0) return;
        
        sqliteDB.executeSql("delete from store where day="+list[0].day,()=>{
            list.map((row)=>{
                if(row.amount==0) return;
                sql.sqlObj = {};
                var sqlobj = sql.table('store').data(row).insert();
                sqliteDB.executeSql(sqlobj,(err)=>{
                    // if(err){ this.getFail(err,param) }
                    // else{ this.getSucc("",param) }
                });
            });
    
            this.getSucc("",param)
        });
    },
    insertToday(param){
        var list = param.objInfo;
        if(list.length<0) return;
        sqliteDB.executeSql("delete from todayinfo",()=>{
            list.map((row)=>{
                sql.sqlObj = {};
                var sqlobj = sql.table('todayinfo').data(row).insert();
                sqliteDB.executeSql(sqlobj,(err)=>{
                    // if(err){ this.getFail(err,param) }
                    // else{ this.getSucc("",param) }
                });
            });
            this.getSucc("",param)
        });
  
    },
    commonQry(param){
      var respInfo = {
        total:0,
        records: []
      };
      var qrysql = this.commonGetQuery(param);
      console.info("commonQry-sql:" , qrysql)
      try{
        sqliteDB.queryData(qrysql,(datas,err)=>{
            if(err){
                this.getFail(err,param) 
            } else{
                respInfo.records = datas;
                if(param.count){
                    var tmpsql = this.commonGetTotal(param);
                    console.info("commonQry-sql-count:" , tmpsql)
                    sqliteDB.queryData(tmpsql,(cntinfo,err)=>{
                        if(err){
                            this.getFail(err,param) 
                        } else{
                            respInfo.total = cntinfo[0]["COUNT(1)"]
                            this.getSucc(respInfo,param) 
                        }
                    });
                }else{
                    this.getSucc(respInfo,param) 
                }

            }
        })
      }catch(ex){
        console.info("commonQry-error-sql:" , ex)
        this.getFail(ex,param)
      }
    },
    execSql(param){
      console.info("execSql-sql:" , param.sql)
      sqliteDB.queryData(param.sql,(datas,err)=>{
        if(err){ this.getFail(err,param) }
        else{ this.getSucc(datas,param) }
      })
    },
    commonGetTotal(param){
        sql.sqlObj = {};
      var tmpsql = sql.count("1").table(param.table).where(param.objInfo);
      if(param.group){
        tmpsql.group(param.group)
      }
      tmpsql.select(true);
      return tmpsql.sqlObj.sqlStr
    },
    commonGetQuery(param){
        sql.sqlObj = {};
      var tmpsql = sql.table(param.table).where(param.objInfo);
      if(param.group){
        tmpsql.group(param.group)
      }
      if(param.order){
        tmpsql.order(param.order)
      }
      if(param.pInfo){
        tmpsql.page(param.pInfo)
      }
      tmpsql.select(true);
      return tmpsql.sqlObj.sqlStr
    }
  }

 
DB.SqliteDB = function(file){
    DB.db = new sqlite3.Database(file);
 
    DB.exist = fs.existsSync(file);
    if(!DB.exist){
        console.log("Creating db file!");
        fs.openSync(file, 'w');
    };
    sqlMgr.isCon = true;
};
 
DB.printErrorInfo = function(err){
    console.log("Error Message:" + err.message + " ErrorNumber:" + err.errno);
};
 
DB.SqliteDB.prototype.createTable = function(sql){
    DB.db.serialize(function(){
        DB.db.run(sql, function(err){
            if(null != err){
                DB.printErrorInfo(err);
                return;
            }
        });
    });
};
 
/// tilesData format; [[level, column, row, content], [level, column, row, content]]
DB.SqliteDB.prototype.insertData = function(sql, objects){
    DB.db.serialize(function(){
        var stmt = DB.db.prepare(sql);
        for(var i = 0; i < objects.length; ++i){
            stmt.run(objects[i]);
        }
    
        stmt.finalize();
    });
};
 
DB.SqliteDB.prototype.queryData = function(sql, callback){
    DB.db.all(sql, function(err, rows){
        if(null != err){
            DB.printErrorInfo(err);
            if(callback){
                callback(rows,err);
            }
            return;
        }
 
        /// deal query data.
        if(callback){
            callback(rows);
        }
    });
};
 
DB.SqliteDB.prototype.executeSql = function(sql,cb){
    DB.db.run(sql, function(err){
        if(null != err){
            DB.printErrorInfo(err);
            if(cb) cb(err);
        }else{
            if(cb) cb("");
        }
    });
};
 
DB.SqliteDB.prototype.close = function(){
    DB.db.close();
};


 
 
var file = config.dbFilePath;
var sqliteDB = new DB.SqliteDB(file);




  

  sqlMgr.initTable();

  ipcMain.on("reCon",(event)=>{
    try{
      sqlMgr.initTable((err)=>{
        event.sender.send('reConRes', err);
      });
    }catch(ex){
      event.sender.send('reConRes', "数据连接失败:"+ex.message);
    }
  });
   
  /**
   * param{
   *  type:  "insertHis",
   *  name: "insertHis",
   *  objInfo: {
   *    sqlInfo
   *  }
   * }
   */
  ipcMain.on("doSql",(event,param)=>{
    param.name = param.name || param.type;
    try{
      if(sqlMgr.isCon){
        param.cb=(res)=>{
          event.sender.send(param.name+'Res', res);
        }
        if(param.execSql){
          sqlMgr.execSql(param);
        }else if(sqlMgr[param.type]){
          sqlMgr[param.type](param);
        }else{
          event.sender.send(param.name+'Res', sqlMgr.getFail("操作方法不存在:"+param.type));
        }
      }else{
        event.sender.send(param.name+'Res', sqlMgr.getFail("数据库未连接"));
      }
    }catch(ex){
      console.error("db error",ex);
      event.sender.send(param.name+'Res', sqlMgr.getFail("数据库操作失败:"+ex.message));
    }
  });
   

// /// insert data.
// var tileData = [[1, 10, 10], [1, 11, 11], [1, 10, 9], [1, 11, 9]];
// var insertTileSql = "insert into tiles(level, column, row) values(?, ?, ?)";
// sqliteDB.insertData(insertTileSql, tileData);
// /// query data.
// var querySql = 'select * from tiles where level = 1 and column >= 10 and column <= 11 and row >= 10 and row <=11';
// sqliteDB.queryData(querySql, dataDeal);
// /// update data.
// var updateSql = 'update tiles set level = 2 where level = 1 and column = 10 and row = 10';
// sqliteDB.executeSql(updateSql);
// /// query data after update.
// querySql = "select * from tiles where level = 2";
// sqliteDB.queryData(querySql, dataDeal);
// sqliteDB.close();
// function dataDeal(objects){
//     for(var i = 0; i < objects.length; ++i){
//         console.log(objects[i]);
//     }
// }
/// export SqliteDB.

exports.SqliteDB = DB.SqliteDB;
